package com.qd.tfpay.test;


import cn.hutool.crypto.SecureUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.jfinal.kit.HashKit;
import com.qd.tfpay.util.SignUtil;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;

import java.util.*;

@Slf4j

public class SignDemo {
    public static void main(String[] args) throws Exception {
        ObjectMapper objectMapper = new ObjectMapper();
        //特约商户key
        String key = "f7d16bef35c740c4884ffc4b9a89ab91";

        //1，获取请求报文主体
        Map<String, Object> map1 = getMap();

        //2.除去数组中的空值和签名参数
        Map<String, String> map3 = paraFilter(map1);

        //3.把数组所有元素排序，并按照“参数=参数值”的模式用“&”字符拼接成字符串 + key
        String str = createLinkString(map3) + key;
        log.info("【MD5】加密前原始串：↓");
        log.info(str);

        //4.生成签名串MD5
        String sign = SecureUtil.md5(str);//16进制  UTF-8  小写
        log.info("【MD5】加密后sgin:↓");
        log.info(sign);
        log.info(HashKit.md5(str));

        //5.请求报文加上 sign和sign_type
        map3.put("sign", sign);
        map3.put("sign_type", "MD5");

        //6.生成请求报文
        String jsonString = objectMapper.writeValueAsString(map3);
        log.info("请求报文：↓");
        log.info(jsonString);
        log.info(SignUtil.createReqJsonStr(map1, key));


    }


    private static Map<String, Object> getMap() {
        Map<String, Object> map2 = new HashMap<>();
        map2.put("service", "pay_service");
        map2.put("service_version", "1.1");
        map2.put("input_charset", "UTF-8");
        map2.put("partner", "12038387");
        map2.put("subpartner", "12038698");
        map2.put("out_trade_no", "frontPayV2018031400010b");
        map2.put("subject", "测试支付产品");
        map2.put("show_url", "http://gys.51peijian.cn");
        map2.put("body", "测试支付00001");
        map2.put("fee_type", "1");
        map2.put("total_fee", "300.11");
        map2.put("spbill_create_ip", "172.0.0.1");
        map2.put("notify_url", "http://172.32.5.32:20003/mock/notify/formReadTimeout");
        map2.put("return_url", "http://localhost:7002/");
        map2.put("trans_pattern", "0");
        map2.put("trans_channel", "wx_qr_a");
        map2.put("trade_details", "12041907^1.59^0^第2笔代收货款^wd0180125s002^0002^0#12038707^1^0^第2笔代收货款^wd0180125a002^0002^0");
        map2.put("biz_type", "0001");
        map2.put("limit_pay", "2");
        map2.put("mobile", "18912318779");
        map2.put("trade_mode", "0002");
        map2.put("time_start", "20180330 06:50:32");
        map2.put("time_expire", "20180330 21:35:23");
        map2.put("attach", "abc");
        map2.put("deliveryaddr", "四川成都武侯区暴力花园320号");
        map2.put("discount", "0.1");
        map2.put("remark", "woshisbeizhu xinxi我是备注信息");
        Map<String, Object> map1 = new HashMap<>();
        map1.put("buyer_id", "2088012237915062");
        map1.put("auth_code", "134758876291626030");
        map1.put("openid", "oZnrsjqJOimY_Z9FHV_6WzhYAnpc");
        map1.put("store_id", "1323728");
        map1.put("bankcode", "496");
        map1.put("qr_return_type", "1");

        map2.put("map", map1);
        return map2;
    }


    /**
     * 除去数组中的空值和签名参数
     *
     * @param sArray 签名参数组
     * @return 去掉空值与签名参数后的新签名参数组
     */
    @SneakyThrows
    public static Map<String, String> paraFilter(Map<String, Object> sArray) {
        ObjectMapper objectMapper = new ObjectMapper();
        Map<String, String> result = new HashMap<>();

        if (sArray == null || sArray.size() == 0) {
            return result;
        }
        for (String key : sArray.keySet()) {
            Object obj = sArray.get(key);
            String value = null;
            if (obj instanceof String) {
                value = String.valueOf(obj);
            } else {
                value = objectMapper.writeValueAsString(obj);
            }
            if ("null".equals(value) || value == null || value.equals("") || key.equalsIgnoreCase("sign")
                    || key.equalsIgnoreCase("sign_type")) {
                continue;
            }
            result.put(key, value);
        }

        return result;
    }

    /**
     * 把数组所有元素排序，并按照“参数=参数值”的模式用“&”字符拼接成字符串
     *
     * @param params 需要排序并参与字符拼接的参数组
     * @return 拼接后字符串
     */
    public static String createLinkString(Map<String, String> params) {

        List<String> keys = new ArrayList<>(params.keySet());
        Collections.sort(keys);
        String prestr = "";
        for (int i = 0; i < keys.size(); i++) {
            String key = keys.get(i);
            String value = params.get(key);
            if (i == keys.size() - 1) {// 拼接时，不包括最后一个&字符
                prestr = prestr + key + "=" + value;
            } else {
                prestr = prestr + key + "=" + value + "&";
            }
        }
        return prestr;
    }


}

class SecondBean {

    private String buyer_id;
    private String auth_code;
    private String openid;
    private String store_id;
    private String bankcode;
    private String qr_return_type;

    public String getBuyer_id() {
        return buyer_id;
    }

    public void setBuyer_id(String buyer_id) {
        this.buyer_id = buyer_id;
    }

    public String getAuth_code() {
        return auth_code;
    }

    public void setAuth_code(String auth_code) {
        this.auth_code = auth_code;
    }

    public String getOpenid() {
        return openid;
    }

    public void setOpenid(String openid) {
        this.openid = openid;
    }

    public String getStore_id() {
        return store_id;
    }

    public void setStore_id(String store_id) {
        this.store_id = store_id;
    }

    public String getBankcode() {
        return bankcode;
    }

    public void setBankcode(String bankcode) {
        this.bankcode = bankcode;
    }

    public String getQr_return_type() {
        return qr_return_type;
    }

    public void setQr_return_type(String qr_return_type) {
        this.qr_return_type = qr_return_type;
    }
}
